package net.cloudcodex.client;

import java.util.ArrayList;

import net.cloudcodex.client.sheet.IsSheet;
import net.cloudcodex.client.sheet.NamedImageSheet;
import net.cloudcodex.client.sheet.Sheet;

import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.util.DOMUtil;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class CloudCodexDnD implements EntryPoint {

	private final ScheduledCommand deferredCommand = new ScheduledCommand() {
		public void execute() {
			final MainView mainView = new MainView();
			final RootPanel rootPanel = RootPanel.get();
			rootPanel.add(mainView);

			final PickupDragController dragController = new PickupDragController(rootPanel, true);

			dragController.registerDropController(mainView);
			dragController.setBehaviorConstrainedToBoundaryPanel(true);
			dragController.setBehaviorDragProxy(false);

			final int clientWidth = DOMUtil.getClientWidth(rootPanel.getElement());
			final int clientHeight = DOMUtil.getClientHeight(rootPanel.getElement());

			for (int i = 0; i < 2; i++) {
				final ArrayList<Sheet> links = new ArrayList<Sheet>();
				final String imageUrl = i % 2 == 0 ? "images/avatar/campaign/default.png" : "images/portevoix.png";
				final NamedImageSheet campaign = new NamedImageSheet("Campaign" + i, imageUrl, links);
				links.add(campaign);

				for (int j = 0; j < 4; j++) {
					final NamedImageSheet character = new NamedImageSheet("Character" + j,
							"images/avatar/character/default.png", links);
					links.add(character);

					final IsSheet title = character.title();

					setRandomPosition(rootPanel, clientWidth, clientHeight, title);

					dragController.makeDraggable(title.asWidget());
					dragController.addDragHandler(character);
				}

				final IsSheet title = campaign.title();

				setRandomPosition(rootPanel, clientWidth, clientHeight, title);

				dragController.makeDraggable(title.asWidget());
				dragController.addDragHandler(campaign);
			}
		}

		private void setRandomPosition(RootPanel rootPanel, int clientWidth, int clientHeight, IsSheet sheet) {
			// add it to the DOM so offset width/height becomes available
			rootPanel.add(sheet, 0, 0);

			// determine random sheet location within target panel
			int left = Random.nextInt(clientWidth - sheet.asWidget().getOffsetWidth());
			int top = Random.nextInt(clientHeight - sheet.asWidget().getOffsetHeight());

			// clear the sheet from MainView
			if (left > (clientWidth / 2 - 400) && left < (clientWidth / 2)) {
				left -= 400;
			}
			if (left < (clientWidth / 2 + 400) && left > (clientWidth / 2)) {
				left += 400;
			}

			// move the sheet
			rootPanel.setWidgetPosition(sheet.asWidget(), left, top);
		}
	};

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		// set uncaught exception handler
		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
			public void onUncaughtException(Throwable throwable) {
				String text = "Uncaught exception: ";
				while (throwable != null) {
					StackTraceElement[] stackTraceElements = throwable.getStackTrace();
					text += throwable.toString() + "\n";
					for (int i = 0; i < stackTraceElements.length; i++) {
						text += "    at " + stackTraceElements[i] + "\n";
					}
					throwable = throwable.getCause();
					if (throwable != null) {
						text += "Caused by: ";
					}
				}
				DialogBox dialogBox = new DialogBox(true, false);
				DOM.setStyleAttribute(dialogBox.getElement(), "backgroundColor", "#ABCDEF");
				System.err.print(text);
				text = text.replaceAll(" ", "&nbsp;");
				dialogBox.setHTML("<pre>" + text + "</pre>");
				dialogBox.center();
			}
		});

		// use a deferred command so that the handler catches exceptions
		Scheduler.get().scheduleDeferred(deferredCommand);
	}

}
